package com.xbongbong.paas.service.async;

import com.xbongbong.callback.help.ApiCallbackHelper;
import com.xbongbong.i18n.util.I18nMessageUtil;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.domain.entity.PaasFormDataEntity;
import com.xbongbong.paas.domain.entity.PaasMenuEntity;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.log.constant.CrmLogMemoConstant;
import com.xbongbong.paas.log.constant.LogMemoConstant;
import com.xbongbong.paas.model.PaasMenuModel;
import com.xbongbong.paas.redis.PaasRedisHelper;
import com.xbongbong.paas.redis.RedisPrefixConstant;
import com.xbongbong.paas.redis.RedisTimeConstant;
import com.xbongbong.paas.service.dynamic.help.DynamicDetailsHelper;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.paas.toolbox.util.DateTimeUtil;
import com.xbongbong.pro.customercommunicate.pojo.dto.CustomerDynamicAddDTO;
import com.xbongbong.pro.customercommunicate.pojo.dto.DynamicDTO;
import com.xbongbong.pro.enums.DistributorMarkEnum;
import com.xbongbong.pro.enums.SaasMarkEnum;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.constant.ListBatchConstant;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.domain.entity.ContractUserEntity;
import com.xbongbong.saas.domain.entity.CustomerUserEntity;
import com.xbongbong.saas.domain.entity.OpportunityUserEntity;
import com.xbongbong.saas.domain.entity.ext.ContractEntityExt;
import com.xbongbong.saas.domain.entity.ext.CustomerEntityExt;
import com.xbongbong.saas.domain.entity.ext.OpportunityEntityExt;
import com.xbongbong.saas.enums.OperateTypeEnum;
import com.xbongbong.saas.enums.ProjectLogEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.CustomerManagementEnum;
import com.xbongbong.saas.model.ContractModel;
import com.xbongbong.saas.model.ContractUserModel;
import com.xbongbong.saas.model.CustomerModel;
import com.xbongbong.saas.model.CustomerUserModel;
import com.xbongbong.saas.model.OpportunityModel;
import com.xbongbong.saas.model.OpportunityUserModel;
import com.xbongbong.saas.service.CustomerCommunicateService;
import com.xbongbong.saas.toolbox.help.FastJsonHelper;
import com.xbongbong.sys.domain.entity.UserEntity;
import org.apache.commons.collections4.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Lazy;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 交接相关异步任务
 * @author kaka
 * @version v1.0
 * @date 2019/6/11 19:21
 * @since v1.0
 */
@Component("workHandoverAsync")
public class WorkHandoverAsync {

    private static final Logger LOG = LoggerFactory.getLogger(WorkHandoverAsync.class);

    @Resource
    private CustomerUserModel customerUserModel;
    @Resource
    private OpportunityUserModel opportunityUserModel;
    @Resource
    private ContractUserModel contractUserModel;

    @Resource
    private PaasRedisHelper paasRedisHelper;
    @Resource
    private ApiCallbackHelper apiCallbackHelper;
    @Resource
    private CustomerModel customerModel;
    @Resource
    private OpportunityModel opportunityModel;
    @Resource
    private ContractModel contractModel;
    @Resource
    @Lazy
    private CustomerCommunicateService customerCommunicateService;
    @Resource
    private DynamicDetailsHelper dynamicDetailsHelper;
    @Resource
    private PaasMenuModel paasMenuModel;
    /**
     * 异步执行交接业务
     * @param corpid 公司id
     * @param userId 操作人userId
     * @param fromUser 交接源员工
     * @param toUser 交接目标员工
     */
    @Async(value = "workHandoverThreadPool")
    public void workHandoverThread(String corpid, String userId, UserEntity fromUser, UserEntity toUser,String loginUserName) {
        String fromUserId = fromUser.getUserId();
        String toUserId = toUser.getUserId();
        String toUserName = toUser.getName();
        String toUserAvatar = toUser.getAvatar();

        String redisKey = corpid + "_" + userId;
        paasRedisHelper.setValue(RedisPrefixConstant.WORK_HANDOVER, redisKey, "2", RedisTimeConstant.TEN_MINUTES);

        Map<String, Object> param = new HashMap<>(16);
        param.put("corpid", corpid);
        param.put("del", 0);
        param.put("userId", fromUserId);
        param.put("isMain", 1);

        try {
            /*
             * 注：需要考虑接收人已经在销售团队中的情况
             */
            //客户
            List<CustomerUserEntity> customerUserList = customerUserModel.findEntitys(param);
            long nowInt = DateTimeUtil.getInt();
            if (customerUserList != null && customerUserList.size() > 0) {
                List<Long> customerIdList = new ArrayList<>(customerUserList.size());

                for (CustomerUserEntity customerUserEntity : customerUserList) {
                    customerIdList.add(customerUserEntity.getDataId());
                    Integer customerId = customerUserEntity.getDataId().intValue();
                    CustomerUserEntity target = customerUserModel.getByUserIdCustomerId(corpid, toUserId, customerId);
                    if (target == null) {
                        //接收人不在团队内--更新原来的
                        customerUserEntity.setUserId(toUserId);
                        customerUserEntity.setUserName(toUserName);
                        customerUserEntity.setAddTime(nowInt);
                        customerUserEntity.setUpdateTime(nowInt);
                        customerUserModel.update(customerUserEntity);
                    }else {
                        //客户关联表没有del字段
                        customerUserModel.delete(customerUserEntity);

                        target.setIsMain(1);
                        target.setUpdateTime(nowInt);
                        customerUserModel.update(target);
                    }
                }
                //员工交接添加客户动态日志,获取fromUser的所有客户实体
                List<CustomerEntityExt> customerEntityExts = customerModel.getByKeys(customerIdList, corpid);
                Map<Long, Integer> menuIdToDistributeMarkMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                try {
                    List<Long> menuIds = customerEntityExts.stream().map(PaasFormDataEntity::getMenuId).collect(Collectors.toList());
                    if (CollectionUtils.isNotEmpty(menuIds)) {
                        Map<String, Object> params = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                        params.put(StringConstant.CORPID, corpid);
                        params.put(StringConstant.DEL, DelEnum.NORMAL.getDel());
                        params.put(StringConstant.IDIN, menuIds);
                        params.put(StringConstant.COLUMNS, "distributor_mark , id");
                        menuIdToDistributeMarkMap = paasMenuModel.findEntitys(params).stream().collect(Collectors.toMap(PaasMenuEntity::getId, PaasMenuEntity::getDistributorMark));
                    }
                } catch (Exception e) {
                    LOG.error("异步执行交接业务查询菜单失败：", e);
                }
                List<DynamicDTO> dynamicDTOS = new ArrayList<>(customerEntityExts.size());
                List<CustomerDynamicAddDTO> customerDynamicAddDTOS = new ArrayList<>(customerEntityExts.size());
                Iterator<CustomerEntityExt> iterator = customerEntityExts.iterator();
                while (iterator.hasNext()){
                    CustomerEntityExt entity = iterator.next();
                    String customerName = FastJsonHelper.getStringOrDefaultFromFormData(entity.getData(), CustomerManagementEnum.NAME.getAttr(), "");
                    Integer distributorMark = menuIdToDistributeMarkMap.get(entity.getMenuId());
                    if (Objects.equals(DistributorMarkEnum.DISTRIBUTOR.getCode(), distributorMark)) {
                        String communicateMemo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.CUSTOMER_TRANSFER), loginUserName, customerName, fromUser.getName(), toUserName);
                        CustomerDynamicAddDTO customerDynamicAddDTO = CustomerDynamicAddDTO.initCustomerDynamicAddDTO(corpid, userId, null, communicateMemo, entity.getId(), customerName, 0L, null, "", ProjectLogEnum.CUSTOMER_HANDOVER.getSubType());
                        customerDynamicAddDTO.setDistributorMark(distributorMark);
                        customerDynamicAddDTOS.add(customerDynamicAddDTO);
                    } else {
                        DynamicDTO dynamicDTO = dynamicDetailsHelper.initDynamicDTO(userId, CrmLogMemoConstant.DYNAMIC_USER_CUSTOMER_TRANSFER, ProjectLogEnum.CUSTOMER_HANDOVER.getSubType(),
                                DynamicDTO.initMemoHolder(loginUserName, I18nMessageUtil.getMessage(ListBatchConstant.MAIN_USER_ALIAS), fromUser.getName(), toUserName), null, null, entity.getId());
                        dynamicDTOS.add(dynamicDTO);
                    }
                }
                if (CollectionUtils.isNotEmpty(dynamicDTOS)) {
                    dynamicDetailsHelper.insertDynamic(dynamicDTOS, corpid);
                }
                if (CollectionUtils.isNotEmpty(customerDynamicAddDTOS)) {
                    customerCommunicateService.batchAddCustomerDynamic(customerDynamicAddDTOS, corpid);
                }

                //api回调（客户）+ 数据评分计算
                List<CustomerEntityExt> customerByKeys = customerModel.getByKeys(customerIdList, corpid);
                if (Objects.nonNull(customerByKeys)) {
                    for (CustomerEntityExt customerEntityExt : customerByKeys) {
                        //api回调
                        apiCallbackHelper.callback4Special(corpid, SaasMarkEnum.SAAS.getCode(), customerEntityExt.getId(), OperateTypeEnum.EDIT, XbbRefTypeEnum.CUSTOMER);

                        //评分更新（工作移交）工作移交只是修改团队，不触发评分更新
                    }
                }
            }

            // 销售机会
            List<OpportunityUserEntity> opportunityUserList = opportunityUserModel.findEntitys(param);
            if (Objects.nonNull(opportunityUserList) && opportunityUserList.size() > 0) {
                List<Long> opportunityIds = new ArrayList<>(opportunityUserList.size());
                for (OpportunityUserEntity oppUser : opportunityUserList) {
                    opportunityIds.add(oppUser.getDataId());
                    Map<String,Object> paramMap = new HashMap<>();
                    paramMap.put(StringConstant.CORPID,corpid);
                    paramMap.put(BasicConstant.USERID,toUserId);
                    paramMap.put(StringConstant.DATA_ID,oppUser.getDataId().intValue());
                    paramMap.put(StringConstant.DEL, DelEnum.NORMAL);
                    List<OpportunityUserEntity> opportunityUserEntityList = opportunityUserModel.findEntitys(paramMap);
                    if (CollectionsUtil.isEmpty(opportunityUserEntityList)) {
                        //接收人不在团队内--更新原来的
                        oppUser.setUserId(toUserId);
                        oppUser.setUserName(toUserName);
                        oppUser.setUserAvatar(toUserAvatar);
                        oppUser.setAddTime(nowInt);
                    } else {
                        //把移交人的del置为1
                        oppUser.setDel(1);
                        for (int i = 0; i < opportunityUserEntityList.size(); i++) {
                            OpportunityUserEntity opportunityUserEntity = opportunityUserEntityList.get(i);
                            opportunityUserEntity.setIsMain(1);
                            opportunityUserEntity.setUpdateTime(nowInt);
                            if (i == 0) {
                                opportunityUserEntity.setDel(0);
                            } else {
                                opportunityUserEntity.setDel(1);
                            }
                        }
                        opportunityUserModel.updateBatch(opportunityUserEntityList, corpid);
                    }
                    oppUser.setUpdateTime(nowInt);
                    opportunityUserModel.update(oppUser);
                }
                //api回调（销售机会）
                Map<String,Object> map = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                map.put("corpid",corpid);
                map.put("del",0);
                map.put("idIn",opportunityIds);
                List<OpportunityEntityExt> opportunityEntityExtList = opportunityModel.findEntitys(map);
                if (Objects.nonNull(opportunityEntityExtList)) {
                    for (OpportunityEntityExt opportunityEntityExt : opportunityEntityExtList) {
                        apiCallbackHelper.callback4Special(corpid, SaasMarkEnum.SAAS.getCode(),
                                opportunityEntityExt.getId(), OperateTypeEnum.EDIT, XbbRefTypeEnum.SALES_OPPORTUNITY);
                    }
                }
            }

            // 合同
            List<ContractUserEntity> contractUserList = contractUserModel.findEntitys(param);
            if (Objects.nonNull(contractUserList) && contractUserList.size() > 0) {
                List<Long> contractIds = new ArrayList<>(contractUserList.size());
                for (ContractUserEntity contractUser : contractUserList) {
                    contractIds.add(contractUser.getDataId());
                    Map<String, Object> paramMap = new HashMap<>();
                    paramMap.put(StringConstant.CORPID, corpid);
                    paramMap.put(BasicConstant.USERID, toUserId);
                    paramMap.put(StringConstant.DATA_ID, contractUser.getDataId().intValue());
                    paramMap.put(StringConstant.DEL, DelEnum.NORMAL);
                    List<ContractUserEntity> contractUserEntityList = contractUserModel.findEntitys(paramMap);
                    if (CollectionsUtil.isEmpty(contractUserEntityList)) {
                        //接收人不在团队内--更新原来的
                        contractUser.setUserId(toUserId);
                        contractUser.setUserName(toUserName);
                        contractUser.setUserAvatar(toUserAvatar);
                        contractUser.setAddTime(nowInt);
                    } else {
                        //把移交人的del置为1
                        contractUser.setDel(1);
                        for (int i = 0; i < contractUserEntityList.size(); i++) {
                            ContractUserEntity contractUserEntity = contractUserEntityList.get(i);
                            contractUserEntity.setIsMain(1);
                            contractUserEntity.setUpdateTime(nowInt);
                            if (i == 0) {
                                contractUserEntity.setDel(0);
                            } else {
                                contractUserEntity.setDel(1);
                            }
                        }
                        contractUserModel.updateBatch(contractUserEntityList, corpid);
                    }
                    contractUser.setUpdateTime(nowInt);
                    contractUserModel.update(contractUser);
                }
                //api回调（合同）
                Map<String,Object> map = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                map.put("corpid",corpid);
                map.put("del",0);
                map.put("idIn", contractIds);
                List<ContractEntityExt> contractEntityExts = contractModel.findEntitys(map);
                if (Objects.nonNull(contractEntityExts)) {
                    for (ContractEntityExt contractEntityExt : contractEntityExts) {
                        apiCallbackHelper.callback4Special(corpid, SaasMarkEnum.SAAS.getCode(),
                                contractEntityExt.getId(), OperateTypeEnum.EDIT, XbbRefTypeEnum.CONTRACT);
                    }
                }
            }
        } catch (Exception e) {
            LOG.error("workHandoverThread 执行出错", e);
            paasRedisHelper.setValue(RedisPrefixConstant.WORK_HANDOVER, redisKey, "3", RedisTimeConstant.MINI_DURATION);
        }

        // 成功和失败状态缓存3秒
        paasRedisHelper.setValue(RedisPrefixConstant.WORK_HANDOVER, redisKey, "1", RedisTimeConstant.MINI_DURATION);
    }

}
